package com.nx.platform.entry.utility;

import com.nx.platform.openentry.entity.ServiceHeaderEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.ServletRequestDataBinder;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * @author alex
 * @brief
 * @date 2020/3/31
 */

@Slf4j
public class RequestUtils {

    /**
     * 将Request参数 封装成对象 当出错 返回null
     *
     * @param request HttpServletRequest
     * @param clazz   Class
     * @param <T>     T
     * @return T
     */
    public static <T> T convertHttpParam(HttpServletRequest request, Class<T> clazz) {
        T bean = null;
        try {
            bean = clazz.newInstance();
            ServletRequestDataBinder servletBinder = new ServletRequestDataBinder(bean);
            servletBinder.bind(request);
        } catch (Exception e) {
            log.error("convert Bean from Request fail " + clazz.getName(), e.getMessage());
        }
        return bean;
    }

    public static String getRemoteAddr(HttpServletRequest httprequest) {
        String ip = httprequest.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = httprequest.getHeader("Proxy-Client-IP");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = httprequest.getHeader("WL-Proxy-Client-IP");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = httprequest.getRemoteAddr();
        }

        if (ip.contains(",")) {
            ip = ip.split(",")[0];
        }

        return ip;
    }

    public static Map<String, String> buildMapFromRequest(HttpServletRequest request) {
        Map<String, String> map = new HashMap<String, String>();
        Enumeration<String> names = request.getParameterNames();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            if (!StringUtils.isEmpty(request.getParameter(name))) {
                map.put(name, request.getParameter(name).trim());
            }
        }
        Enumeration<String> attrs = request.getAttributeNames();
        while (attrs.hasMoreElements()) {
            String name = attrs.nextElement();
            if (!StringUtils.isEmpty(request.getAttribute(name) + "")) {
                map.put(name, request.getAttribute(name) + "");
            }
        }
        Cookie[] cookies = request.getCookies();
        if (cookies != null && cookies.length > 0) {
            for (Cookie cookie : cookies) {
                map.put(cookie.getName(), cookie.getValue());
            }
        }
        log.info("desc=build_map_from_request map={}", CommonUtil.getGson().toJson(map));
        return map;
    }

    public static ServiceHeaderEntity buildHeader(HttpServletRequest request) {

        ServiceHeaderEntity header = new ServiceHeaderEntity();
        header.setServiceInvocationDepth(1);
        header.setReqUid((Long)request.getAttribute("uid"));
        header.setToken((String) request.getAttribute("t"));
        header.setLat((String) request.getAttribute("lat"));
        header.setLon((String) request.getAttribute("lon"));
        Object version = request.getAttribute(Constant.VERSION);
        header.setVersion(version == null ? null : String.valueOf(version));
        String clientIp = RequestUtils.getRemoteAddr(request);
        header.setClientIp(clientIp);
        if (request.getCookies() != null && request.getCookies().length > 0){
            header.setCookies(new HashMap<>());//新建cookiemap
            for (Cookie cookie : request.getCookies()){
                if (StringUtils.isNotEmpty(cookie.getValue()) // 已存入header里的cookie字段不在重复放入cookieMap
                        && (request.getAttribute(cookie.getName()) == null
                        ||  StringUtils.isEmpty(String.valueOf(request.getAttribute(cookie.getName()))))){
                    header.getCookies().put(cookie.getName(), cookie.getValue());
                }
            }
        }

        return header;
    }

}
